package cn.roadtrip.musermodule.bs;

import cn.roadtrip.musermodule.dao.userlayout.LeaderInforsMapper;
import cn.roadtrip.musermodule.dao.userlayout.UserBindRoleMapper;
import cn.roadtrip.musermodule.dao.userlayout.UserInforMapper;
import cn.roadtrip.musermodule.dao.userlayout.po.LeaderInfors;
import cn.roadtrip.musermodule.dao.userlayout.po.UserBindRole;
import cn.roadtrip.musermodule.dao.userlayout.po.UserInforWithBLOBs;
import cn.roadtrip.musermodule.dao.userlayout.po.UserLoginBind;
import cn.roadtrip.musermodule.spi.login.UserLogin;
import cn.roadtrip.musermodule.spi.role.ApplyRole;
import cn.roadtrip.umysqlmodule.transaction.TransactionRollback;
import cn.roadtrip.utilmodule.util.DataBean;
import cn.roadtrip.utilmodule.util.enumpck.Enum_LoginPlat;
import cn.roadtrip.utilmodule.util.JWTHelper;
import cn.roadtrip.utilmodule.util.enumpck.Enum_UserBindRoleStats;
import cn.roadtrip.utilmodule.util.enumpck.Enum_UserRoleType;
import com.google.gson.Gson;
import jakarta.annotation.Resource;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Map;

@Slf4j
@Component
public class UserImpl {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private TransactionRollback transactionRollback;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    //用户登录插件
    @Resource
    private PluginRegistry<UserLogin, String> userLoginPluginRegistry;

    @Resource
    private PluginRegistry<ApplyRole, String> applyRolePluginRegistry;

    @Autowired
    private JWTHelper jwtHelper;

    /**
     * @param datas
     * @return
     */
    public DataBean login(
            String agent,
            String loginPlat,
            String clientCode,
            Map<String, String> datas
    ) {
        if (datas == null || datas.size() == 0) {
            return DataBean.err("parm-null", "请求参数错误");
        }
        Enum_LoginPlat ed = Enum_LoginPlat.parseCode(loginPlat);
        if (ed == null)
            return DataBean.err("loginPlat-err", "来源错误");
        DataBean db = null;
        /**
         * 使用插件方式判断登录
         */
        switch (ed) {
            case WeiChatMiniProm:
                db = userLoginPluginRegistry.getRequiredPluginFor(ed.getCode()).loginAndRegistry(datas);
                break;
            default:
                return DataBean.err("loginPlat-invalid", "来源无效");
        }
        if (!db.isSuc())
            return db;
        UserLoginBind cuser = (UserLoginBind) db.getResult();
        Gson gson = new Gson();
        String newtoken = jwtHelper.initTockenCode(
                cuser.getId(),
                loginPlat,
                clientCode,
                "" + agent,
                gson.toJson(cuser)
        );
        db.setToken(newtoken);

        //查询其余绑定得角色
        try (SqlSession sql = sqlSessionFactory.openSession(true)) {
            UserBindRoleMapper roleMapper = sql.getMapper(UserBindRoleMapper.class);
            java.util.List<UserBindRole> roles = roleMapper.getUserRoles(cuser.getUserid());
            java.util.List<String> validRoles = new ArrayList<>();
            for (UserBindRole role : roles) {
                if (role.getStats().equals(Enum_UserBindRoleStats.Active.getCode()))
                    validRoles.add(role.getRoletype());
            }
            db.setOtherProperties(Map.of("roles", validRoles));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return db;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Model_ModifyUserInfor {
        private String userId;//用户ID
        private String telNum;//电话号码
        private String nickName;//昵称
        private String headCover;//头像
        private Map<String, Object> extInfors;//其他信息
    }

    /**
     * 修改用户基本信息
     *
     * @param model 修改对象
     * @return
     */
    public DataBean modifyUserInfor(
            Model_ModifyUserInfor model
    ) {
        return transactionRollback.transaction(
                () -> {
                    try (SqlSession sql = sqlSessionFactory.openSession(true)) {
                        UserInforMapper userMapper = sql.getMapper(UserInforMapper.class);
                        UserInforWithBLOBs user = userMapper.selectByPrimaryKey(model.getUserId());
                        if (user == null) {
                            return DataBean.err("user-null", "查询用户不存在");
                        }
                        user.setNickname(model.getNickName());
                        user.setCover(model.getHeadCover());
                        user.setPhone(model.getTelNum());
                        if (model.getExtInfors() == null || model.getExtInfors().size() == 0) {
                            Gson gson = new Gson();
                            Map<String, Object> infors = gson.fromJson(
                                    user.getExtinfors(),
                                    new com.google.gson.reflect.TypeToken<Map<String, Object>>() {
                                    }.getType()
                            );
                            infors.putAll(model.getExtInfors());
                            user.setExtinfors(gson.toJson(infors));
                        }
                        userMapper.updateByPrimaryKeySelective(user);
                        sql.commit();
                        return DataBean.suc(true, 1, "suc", "操作完成");
                    }
                },
                (ex) -> {
                    return DataBean.err("trans-err", "执行事务错误", ex.getMessage());
                }
        );
    }

    /**
     *
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode
    public static class Module_ApplyUserRole {
        private String userId;
        private String roleType;
        private java.util.Map<String, Object> remark;//备注
    }

    /**
     * 用户申请角色
     *
     * @return
     */
    public DataBean applyUserRole(
            Module_ApplyUserRole model
    ) {
        return applyRolePluginRegistry.getRequiredPluginFor(Enum_UserRoleType.Leader.getCode()).applyRole(model);
    }


    /**
     * 获取领队基本信息
     *
     * @param userId
     * @return
     */
    public DataBean getLeaderInfor(String userId) {
        try (SqlSession sql = sqlSessionFactory.openSession(true)) {
            LeaderInforsMapper mapper = sql.getMapper(LeaderInforsMapper.class);
            LeaderInfors model = mapper.getLeaderInforByUserId(userId);
            if (model == null) {
                return DataBean.err("user-null", "查询用户信息不存在");
            }
            return DataBean.suc(model, 1, "suc", "操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("err", e.getMessage());
        }
    }
}
